package ch.uzh.ifi.ddis.ds2011.a3;

import org.openrdf.rio.RDFHandler;

import ch.uzh.ifi.ddis.ds2011.a3.helper.ParseHelper;
import ch.uzh.ifi.ddis.ds2011.a3.helper.ResultProcessingHelper;
import ch.uzh.ifi.ddis.ds2011.a3.helper.Triple;
import ch.uzh.ifi.ddis.ds2011.a3.helper.TripleHandler;

import com.signalcollect.Graph;
import com.signalcollect.StateForwarderEdge;
import com.signalcollect.javaapi.GraphBuilder;

public class SubClassInference {

	private final static String SUBCLASS = "http://www.w3.org/2000/01/rdf-schema#subClassOf";

	private String filePath;

	/**
	 * Loads an RDF graph and then calculates the transitive closure of the RDFS
	 * subClassOf relationship.
	 * 
	 * @param filePath
	 *            the path of the N-Triples file to load
	 */
	public SubClassInference(String fileName) {
		this.filePath = fileName;
	}

	/**
	 * Loads the RDFS class graph by adding vertices for the subjects and
	 * objects of the subClassOf relationships. Adds an edge going from the
	 * object vertex to the subject vertex for each subClassOf relationship.
	 * 
	 * @param filePath
	 *            the path of the n-triples file to load
	 * @return the initialized RDFS subClassOf graph
	 */
	Graph initializeGraph(String filePath, final String predicate) {
		/** The Signal/Collect compute graph. */
		final Graph g = GraphBuilder.build();
		RDFHandler tripleHandler = new TripleHandler() {

			@Override
			public void handleTriple(Triple triple) {
				if (triple.predicate.equals(predicate)) {
                                    g.addVertex(new AccumulatingVertex(triple.subject));
                                    g.addVertex(new AccumulatingVertex(triple.object));
                                    // müsste noch irgendwie predicate mit...?
                                    g.addEdge((new StateForwarderEdge(triple.subject, triple.object, "subClassOf")));
				}

			}

		};
		ParseHelper.parseNTriplesFileWithHandler(filePath, tripleHandler);
		return g;
	}

	public void findInferences() {
		Graph g = initializeGraph(filePath, SUBCLASS);
		g.execute();
		ResultProcessingHelper.printAllVertices(g);
		g.shutdown();
	}

	/**
	 * Main method, program entry point.
	 * 
	 * @param args
	 *            the arguments, currently ignored
	 */
	public static void main(String[] args) {
		String filePath = "datasets/dbpedia_3.6_subClassOf.nt";
		SubClassInference inference = new SubClassInference(filePath);
		inference.findInferences();
	}
}
